package udpServer

import (
	"errors"
	"net"
	"strings"
	"time"
)

type UdpClient struct {
	IpAddress   string
	Port        int
	EventMap    map[string]interface{}
	conn        *net.UDPConn
	StillRead   bool
	ReadTimeOut time.Duration
}

func (udpClient *UdpClient) Close() error {
	if udpClient.StillRead && udpClient.conn != nil {
		udpClient.StillRead = false
		return udpClient.conn.SetReadDeadline(time.Now())
	}
	return nil
}

func (udpClient *UdpClient) Send(data []byte) error {
	if udpClient.conn == nil {
		return errors.New("无效连接")
	}
	_, err := udpClient.conn.Write(data)
	return err
}
func (udpClient *UdpClient) OnMessage(fun func(data []byte, addr *net.UDPAddr)) {
	udpClient.init()
	udpClient.EventMap[OnMessage] = fun
}

func (udpClient *UdpClient) init() {
	if udpClient.EventMap == nil {
		udpClient.EventMap = make(map[string]interface{})
	}
}

func (udpClient *UdpClient) GetConn() *net.UDPConn {
	return udpClient.conn
}

func (udpClient *UdpClient) Connect() (*net.UDPConn, error) {
	udpClient.init()
	ipAddressList := strings.Split(udpClient.IpAddress, ".")
	if len(ipAddressList) != 4 {
		return nil, errors.New("无效ip地址:" + udpClient.IpAddress)
	}
	conn, err := net.DialUDP("udp", nil, &net.UDPAddr{
		IP:   net.ParseIP(udpClient.IpAddress).To4(),
		Port: udpClient.Port,
	})
	if err != nil {
		return nil, err
	}
	//udpClient.StillRead = true
	go func() {
		for udpClient.StillRead {
			result := make([]byte, 4096)
			if udpClient.ReadTimeOut > 0 {
				err := conn.SetReadDeadline(time.Now().Add(time.Second * udpClient.ReadTimeOut))
				if err != nil {
					break
				}
			}
			n, remoteAddr, err := conn.ReadFromUDP(result)
			if err != nil {
				break
			}
			if fun, ok := udpClient.EventMap[OnMessage]; ok {
				fun.(func(data []byte, addr *net.UDPAddr))(result[:n], remoteAddr)
			}
		}
	}()
	udpClient.conn = conn
	return nil, err
}
